package org.sun.sunshine.utils;


import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.util.*;

/**
 * freemaker 导出word工具类
 * @author yusj
 */
@Slf4j
public class WordUtil {
    //配置信息
    private static Configuration configuration = null;

    //WordUtils的类加载器动态获得模板文件的位置
    private static final String templateFolder = WordUtil.class.getResource("/templates").getPath();

    static {
        configuration = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        configuration.setDefaultEncoding("utf-8");
        try {
            log.debug("freemaker template folder {}",templateFolder);
            configuration.setDirectoryForTemplateLoading(new File(templateFolder));
        } catch (IOException e) {
            log.error("freemaker config error ",e);
        }
    }
    private WordUtil() {
        throw new AssertionError();
    }

    /**
     * 根据freemaker模板生成Word
     * @param request 请求对象
     * @param response 响应对象
     * @param map word文档中参数 freemaker 模板中 用${} 引用
     * @param wordName 为模板的名字  例如xxx.ftl 模板需要在 resource/template/ 目录下
     * @param fileName 是word 文件的名字 格式为："xxxx.docx"
     * @throws IOException
     */
    public static void exportWordByFreemarker(HttpServletRequest request, HttpServletResponse response, Map map,
                                                 String wordName, String fileName) throws IOException {
        Template freemarkerTemplate = configuration.getTemplate(wordName);
        File file = null;
        InputStream fin = null;
        try (ServletOutputStream out = response.getOutputStream();){
            // 调用工具类的createDoc方法生成Word文档
            file = createDoc(map, freemarkerTemplate, UUID.randomUUID().toString());
            fin = Files.newInputStream(file.toPath());
            response.setCharacterEncoding("utf-8");
            response.setContentType("application/x-download");
            fileName = URLEncoder.encode(fileName, StandardCharsets.UTF_8.toString());
            response.setHeader("Content-Disposition", "attachment;filename=".concat(String.valueOf(fileName)));

            byte[] buffer = new byte[512];// 缓冲区
            int bytesToRead = -1;
            // 通过循环将读入的Word文件的内容输出到浏览器中
            while ((bytesToRead = fin.read(buffer)) != -1) {
                out.write(buffer, 0, bytesToRead);
            }
        } finally {
            if (fin != null) fin.close();
            if (file != null) {
                boolean isDeleted = file.delete();
                if (!isDeleted) {
                    log.error("Failed to delete temporary file: {}", file.getAbsolutePath());
                }
            }
        }
    }

    private static File createDoc(Map<?, ?> dataMap, Template template, String name) {
        File f = new File(name);
        try(Writer w = new OutputStreamWriter(Files.newOutputStream(f.toPath()), StandardCharsets.UTF_8);) {
            template.process(dataMap, w);
        } catch (Exception ex) {
            log.error("导出Word失败",ex);
        }
        return f;
    }


    public static void main(String[] args) throws IOException {
        //word 导出demo
        Map<String,Map<String,Object>> docMap=new HashMap<String, Map<String,Object>>();

        Map<String,Object> doc=new HashMap<>();
        doc.put("title","水稻参数采集");
        List<Map<String,Object>> items=new ArrayList<>();
        Map<String,Object> item=new HashMap<>();
        item.put("paramName","千粒重");
        item.put("qlz1",11);
        item.put("qlz2",12);
        item.put("qlz3",13);
        items.add(item);

        Map<String,Object> item1=new HashMap<>();
        item1.put("paramName","叶龄");
        item1.put("qlz1",11);
        item1.put("qlz2",12);
        item1.put("qlz3",13);
        items.add(item1);

        doc.put("items",items);
        docMap.put("doc",doc);

        Template freemarkerTemplate = configuration.getTemplate("freemaker.ftl");
        createDoc(docMap,freemarkerTemplate,"fre.docx");

    }

}

